/**
 * PerlaController - part of PerlaGis Architecture
 *
 * Copyright (C) 2010 Ricardo Gonzalez (gomnaz@gmail.com)
 * This program is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see http://www.gnu.org/licenses/
 */
package org.perla.managers;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import org.gis.services.NoSuchSensorException_Exception;
import org.notify.entities.Relation;
import org.notify.exceptions.NoRelationException;
import org.perla.entities.Attitude;
import org.perla.entities.Bibi;
import org.perla.entities.Temperature;
import org.perla.exceptions.NoSuchSensorException;
import org.perla.exceptions.WrongSensorTypeException;

/**
 * Classe statica che gestisce la comunicazione con il GisController tramite
 * i servizi disponibili.
 * E' possibile chiedere al GisController di aggiungere o rimuovere un sensore
 * oppure inviare gli ultimi valori per un dato sensore.
 * 
 * @author Ricardo Gonzalez
 * @author Eva Gjeci
 */
public class Gis {

    /**
     * Chiede al GisController di creare un nuovo sensore. Restituisce la
     * chiave del nuovo sensore.
     * 
     * @param name il nome da attribuire al sensore
     * @return la chiave del sensore
     * @return -1 se ci sono stati errori.
     */
    public static int addSensor(java.lang.String name) {
        org.gis.services.AdministrationService service = new org.gis.services.AdministrationService();
        org.gis.services.Administration port = service.getAdministrationPort();
        return port.addSensor(name);
    }

    /**
     * Chiede al GisController di rimuovere il sensore identificato dalla chiave
     * passata come parametro.
     *
     * @param idSensore la chiave del sensore da rimuovere
     * @return true se l'operazione ha avuto successo
     * @throws NoSuchSensorException_Exception se il sensore indicato non esiste
     */
    public static boolean removeSensor(int idSensore) throws NoSuchSensorException_Exception {
        org.gis.services.AdministrationService service = new org.gis.services.AdministrationService();
        org.gis.services.Administration port = service.getAdministrationPort();
        return port.removeSensor(idSensore);
    }

    /**
     * Invia al GisController gli ultimi valori per il nodo passato come parametro.
     * Il nodo deve appartenere ad almeno una relazione Perla-Gis, di cui sia
     * stata chiesta la notifica.
     * 
     * @param idNodo la chiave del nodo per cui inviare i valori
     * @param emPerla l'entity manager per il Perla
     * @param emRelation l'entity manager per il notify
     * @throws NoSuchSensorException se il sensore indicato non esiste o non fa parte di una relazione
     */
    public static void sendUpdate(java.lang.String idNodo, EntityManager emPerla, EntityManager emRelation) throws NoSuchSensorException {
        try {
            //Carica gli ultimi valori per il nodo
            Attitude a = Value.getLastAttitude(Sensor.get(idNodo, "ATTITUDE_" + idNodo, emPerla), emPerla);
            Temperature t = Value.getLastTemperature(Sensor.get(idNodo, "TEMPERATURE_" + idNodo, emPerla), emPerla);
            Bibi b = Value.getLastBibi(Sensor.get(idNodo, "BIBI_" + idNodo, emPerla), emPerla);

            float attitude = (float) a.getAttitudeX();
            float bibi = (float) b.getMagnitudez();
            short temperature = (short) t.getValue().floatValue();

            org.gis.services.OperativeService service = new org.gis.services.OperativeService();
            org.gis.services.Operative port = service.getOperativePort();

            //Carica la lista delle relazioni contenenti il nodo passato come parametro
            List<Relation> l = Notify.getRelations(idNodo, emRelation);

            //Per ogni relazione, se la notifica è attiva, invia il valore al GisController
            for (Relation r : l) {
                if (r.getNotifica()) {
                    port.receiveUpdate(r.getIdSensoreGis(), attitude, bibi, temperature);
                }
            }

        } catch (WrongSensorTypeException ex) {
            Logger.getLogger(Gis.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchSensorException_Exception ex) {
            Logger.getLogger(Gis.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoRelationException ex) {
            Logger.getLogger(Gis.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
